import numpy as np

def restriction_function(chrom: np.ndarray, v_number: int) -> np.ndarray:
    """
    根据形状特征的限制条件筛选合法的染色体。

    Parameters:
    chrom (np.ndarray): 染色体数组
    v_number (int): 变量数量

    Returns:
    np.ndarray: 合法的染色体数组
    """
    # 获取各个操作的索引
    index_of_1 = np.where(chrom == 1)[1]
    index_of_2 = np.where(chrom == 2)[1]
    index_of_5 = np.where(chrom == 5)[1]
    index_of_6 = np.where(chrom == 6)[1]
    index_of_7 = np.where(chrom == 7)[1]
    index_of_8 = np.where(chrom == 8)[1]
    index_of_9 = np.where(chrom == 9)[1]
    index_of_10 = np.where(chrom == 10)[1]
    index_of_11 = np.where(chrom == 11)[1]
    index_of_12 = np.where(chrom == 12)[1]
    index_of_13 = np.where(chrom == 13)[1]

    # 筛选合法的染色体
    legal_indices = []

    def check_legal(index_of_op, index_of_ref):
        return np.where((index_of_op - index_of_ref) > 0)[0]

    legal_indices.extend(check_legal(index_of_6, index_of_1))
    legal_indices.extend(check_legal(index_of_6, index_of_2))
    legal_indices.extend(check_legal(index_of_6, index_of_5))

    legal_indices.extend(check_legal(index_of_7, index_of_1))
    legal_indices.extend(check_legal(index_of_7, index_of_2))
    legal_indices.extend(check_legal(index_of_7, index_of_5))

    legal_indices.extend(check_legal(index_of_8, index_of_1))
    legal_indices.extend(check_legal(index_of_8, index_of_2))
    legal_indices.extend(check_legal(index_of_8, index_of_5))

    legal_indices.extend(check_legal(index_of_9, index_of_1))
    legal_indices.extend(check_legal(index_of_9, index_of_2))
    legal_indices.extend(check_legal(index_of_9, index_of_5))

    legal_indices.extend(check_legal(index_of_10, index_of_1))
    legal_indices.extend(check_legal(index_of_10, index_of_2))
    legal_indices.extend(check_legal(index_of_10, index_of_5))

    legal_indices.extend(check_legal(index_of_11, index_of_1))
    legal_indices.extend(check_legal(index_of_11, index_of_2))
    legal_indices.extend(check_legal(index_of_11, index_of_5))

    legal_indices.extend(check_legal(index_of_12, index_of_1))
    legal_indices.extend(check_legal(index_of_12, index_of_2))
    legal_indices.extend(check_legal(index_of_12, index_of_5))

    legal_indices.extend(check_legal(index_of_13, index_of_1))
    legal_indices.extend(check_legal(index_of_13, index_of_2))
    legal_indices.extend(check_legal(index_of_13, index_of_5))

    legal_indices = np.unique(legal_indices)
    legal_indices = legal_indices.astype(int)  # 确保索引是整数
    legal_individual = chrom[legal_indices]

    return legal_individual

def get_objective_value(chrom: np.ndarray, decode_filename: str, weight: np.ndarray) -> np.ndarray:
    decode_array = np.loadtxt(decode_filename)
    machine_change_times = np.empty((chrom.shape[0], 1))
    tool_change_times = np.empty((chrom.shape[0], 1))
    install_change_times = np.empty((chrom.shape[0], 1))

    for i in range(chrom.shape[0]):
        machine_serial = decode_array[chrom[i, :] - 1, 2]
        tool_serial = decode_array[chrom[i, :] - 1, 3]
        install_base_serial = decode_array[chrom[i, :] - 1, 4]

        machine_change = machine_serial[1:] - machine_serial[0:-1]
        machine_change_times[i, 0] = np.count_nonzero(machine_change)

        tool_change = tool_serial[1:] - tool_serial[0:-1]
        tool_change_times[i, 0] = np.count_nonzero(tool_change)

        install_base_change = install_base_serial[1:] - install_base_serial[0:-1]
        install_base_change_on_same_machine = np.logical_and((machine_change == 0), (install_base_change != 0))
        install_change_times[i, 0] = machine_change_times[i, 0] + np.sum(install_base_change_on_same_machine)

    objective_value = machine_change_times * weight[0] + tool_change_times * weight[1] + install_change_times * weight[2]
    chrom_with_objective = np.hstack((chrom, objective_value))
    return chrom_with_objective
